/*--------------------------------【补充内容】
一、exists关键字的用法
1、exists关键字
  exists关键字是存在条件判定关键字；
  类似于java的if语句；
  exists操作符用于判定子查询的结果是否存在，返回的的值是true或false；
        当子查询结果存在，返回true，当子查询结果不存在，返回false；
  主查询根据exists返回的结果，决定是否将当前的这条记录放入查询结果集中；
  
  注意：
      exists返回的结果不是子查询的结果，是一个布尔类型的变量，true或false；
      exists用法是当子查询有结果时，当前主查询被关联这条记录放入结果集中，否则不放入结果集；
 
  not exists用法：
      和exists用法相反，当子查询没有查到结果时，返回true；当子查询查到了结果，返回false；

   总结：
       exists中的子查询的结果没有用，只是用于exists作为返回值的判定依据；
       根据exists返回的true或false来决定当前主查询所关联这条记录是否放在查询结果中；
       
       exists的执行效率要高于使用 in 、not in之类等价操作；
       
2、子查询分类
   根据子查询和主查询之间有没有关联条件，分为：
       相关子查询；
           一般用于 exists关键字，
           在子查询的关联条件中会引用到主查询表中的字段；
           
       非相关子查询；
           在子查询中不会引用主查询中的表；
           子查询和主查询是独立完成的，没有关联关系；
           
二、集合操作
    两个查询结果集之间可以对查询结果进行集合操作；
    常用的操作有：
        并集、减集、交集
    注意：
       集合操作要求进行集合操作的两个结果集的字段个数相同，每个字段的类型要兼容；
       
1、并集操作
   把两个查询结果集合并在一起，叫做并集；
   union 、union all 
   
   注意：
       要求进行并集操作的两个结果集的字段个数相同，每个字段的类型要兼容；
       union 合并时会剔除重复的行；
       union all 合并时不会剔除重复的行； 

2、补集(减集)操作
   minus关键字：从一个集合中将与另一个集合重复的部分剔除之后剩余的集合；
                从一个集合中剔除与另外一个集合交集的部分之后剩余的集合；
                
3、交集操作
   INTERSECT关键字：
      两个集合相互重合部分；
      
三、分页查询
1、rowid、rownum伪列
   rowid：Oracle给每个查询结果集中的每条记录自动分配的一个唯一标识符；
         一般Oracle内部进行修改删除新增等操作的标示字段；
   rownum：Oracle给每个查询结果集提供的一个从1开始的顺序标号；
          例如如果查询结果集中有5条记录，则Oracle分配的标号是从1-5；
   注意：
        rownum 是随着结果集存在而存在，而且，不管什么样的查询结果集，rownum永远是从1开始的；
        
          
2、Oracle分页查询的实现方式                
   （1）rownum集合子查询实现；
   （2）使用补集操作；
   
三、层次查询   
    使用层次查询可以根据树型的组织结构关系进行查询；
    语法：
        select [level]显示列表 from 表名 where 条件
            start with 开始条件
            connect by prior 关联条件；
     
    解析：
        （1）level是一个伪列，显示层次关系的第几层；
        （2）start with 后面是开始条件
        （3）connect by prior 后面表示的是上下级关系
     
    层次查询中对分支的过滤修建处理：
    
    （1） 过滤条件写在where中，则只过滤一个节点；
    （2）过滤条件写在 connect by prior 后面，则会过滤一个分支； 
   
【补充内容】--------------------------------*/
select * from employees;
select * from departments;
--- exists关键字用法
-- 查询部门名称为 it的所有的员工
select e.* from employees e ,departments d 
       where e.department_id = d.department_id and upper(d.department_name)= upper('IT');

-- exists 查询

select * from employees e where exists (
       select * from departments d    -- 子查询引用了主查询表e中的字段，这是相关子查询
              where e.department_id = d.department_id and upper(d.department_name)= upper('IT')
       );

--- 查询不是it部门的员工信息
select * from employees e where not exists (
       select * from departments d 
              where e.department_id = d.department_id and upper(d.department_name)= upper('IT')
       );

--- 并集
select * from employees;
select * from job_history;
-- 查询employees表
select e.employee_id,e.job_id,e.department_id from employees e where e.department_id = 60;

-- 查询job_history表
select j.employee_id,j.job_id,j.department_id from job_history j where j.department_id = 80;

--- 并集
select e.employee_id,e.job_id,e.department_id from employees e where e.department_id = 60
union
select j.employee_id,j.job_id,j.department_id from job_history j where j.department_id = 80;

-- union 剔除重复的行
select e.employee_id,e.job_id,e.department_id from employees e where e.department_id = 60
union
select e.employee_id,e.job_id,e.department_id from employees e where e.department_id = 60;
-- union all 不剔除重复的行
select e.employee_id,e.job_id,e.department_id from employees e where e.department_id = 60
union all
select e.employee_id,e.job_id,e.department_id from employees e where e.department_id = 60;

----- 补集
select e.employee_id,e.job_id,e.department_id from employees e 
minus
select j.employee_id,j.job_id,j.department_id from job_history j ;

--- 交集
select e.employee_id,e.job_id,e.department_id from employees e 
intersect
select j.employee_id,j.job_id,j.department_id from job_history j ;

---- Oracle 中的 rowid和rownum伪列
select rownum as rowIndex,e.employee_id,e.job_id,e.department_id,rowid 
       from employees e where e.department_id=60;
       
--- 分页查询：使用rownum伪列实现

-- 显示查询结果中的前5条
select rownum as rowIndex,e.employee_id,e.job_id,e.department_id
       from employees e where rownum <= 5;

-- 显示查询结果中的第6-10条
select rownum as rowIndex,e.employee_id,e.job_id,e.department_id
       from employees e where rownum > 5 and rownum <= 10;
       
--- 子查询+rownum实现分页查询
select * from (
         select rownum  as rowIndex,e.employee_id,e.job_id,e.department_id
                from employees e
              )  t where t.rowIndex >5 and t.rowIndex <=10;

--- 使用集合的补集操作完成分页查询
-- 显示查询结果中的第6-10条
select rownum as rowIndex,e.employee_id,e.job_id,e.department_id
       from employees e where rownum <= 10
minus
select rownum as rowIndex,e.employee_id,e.job_id,e.department_id
       from employees e where rownum <= 5
       
--- 层次查询

select * from employees;       

--- 查询id编号为100的经理下面的所有的员工【层次关系】
select * from employees e 
      start with employee_id = 103   --- 从员工id为100的这个人开始进行层次查询
      connect by prior  employee_id = manager_id;  ---  从上往下
       
--- 查询id编号为100的经理下面的所有的员工【层次关系】
select * from employees e 
      start with employee_id = 100   --- 从员工id为100的这个人开始进行层次查询
      connect by prior  manager_id = employee_id;  ---  从下往上      

--- 层次查询中对于分支的修建处理
--- where条件过滤一个点
select * from employees e where employee_id <> 103
      start with employee_id = 100   --- 从员工id为100的这个人开始进行层次查询
      connect by prior  employee_id = manager_id;  ---  从上往下
      
--- connect by prior条件过滤一个分支
select * from employees e  
      start with employee_id = 100   --- 从员工id为100的这个人开始进行层次查询
      connect by prior  employee_id = manager_id and employee_id <> 103;  ---  从上往下            